王子和公主合力抵抗壞皇后,他們費盡了千辛萬苦,終於打敗了壞皇后,以為從此就能過著幸福快樂美滿的日子,但是錯了,他們還有各自的王子病和公主病要先治療....
我想畫一個散佈圖,我用canvas
為什麼不用人家寫好的套件,因為別人寫好的套件不一定是我要的東西(好啦我承認是因為老闆太喜歡搞自己的格調改來改去,別人的套件風格都定義好了幾乎沒得改)
jquery這麼方便我竟然不用,因為裡面有太多的try{}catch{},我的東西很簡單,沒有表格排序沒有下拉選單要作業,所以在這裡我不需要jquery
好吧,用canvas也沒什麼特別的,就是要依瀏覽器各別做,不同瀏覽器要另外寫不同做法,遇到IE8還真是憋腳,但是excanvas.js也是能救回來將就一下啦,問題是ie8怎麼有時候OK有時候不OK?看吧~王子病和公主病開始發作了.....
1.xml資料源讀取大不同,是的,我還是用了try catch來針對瀏覽器做不同的xml讀取方式
  var xmlDocTemp;
    if ((xmlFilePath != null) && (xmlFilePath != "")) {
        if (window.ActiveXObject)// code for IE
        {
            xmlDocTemp = new ActiveXObject('Microsoft.XMLDOM');
            xmlDocTemp.async = false;
            xmlDocTemp.load(xmlFilePath);
        }
        else if (window.XMLHttpRequest)// code for IE7, Firefox, Opera, etc.
        {
            try {
                xmlDocTemp = document.implementation.createDocument("", "", null);
                xmlDocTemp.async = false;
                xmlDocTemp.load(xmlFilePath);
            }
            catch (e) {
                try //Google Chrome  safari
					  {
                    xmlhttp = new window.XMLHttpRequest();
                    xmlhttp.onreadystatechange = function () {
                        if (xmlhttp.readyState == 4) {// 4 = "loaded"
                            if (xmlhttp.status == 200) {// 200 = "OK"
                                xmlDocTemp = xmlhttp.responseXML; // alert(xmlhttp.responseXML);
                            }
                        }
                    };
                    xmlhttp.open("GET", xmlFilePath, false);
                    xmlhttp.setRequestHeader('Content-Type', 'text/xml');
                    xmlhttp.send(null);
                }
                catch (e) {
                    error = e.message;
                    alert(error);
                }
            }
        }
        else {
            alert('您的瀏覽器不支持xml文件讀取,請使用 IE5.0以上 或 Chrome 或 FireFox 較高版本來嘗試瀏覽本網頁!');
            return null;
        }
    }
    else
    { return null; }
    try {
        return xmlDocTemp;
    } finally {
        xmlDocTemp = null;
    }
讀取xmlDocument時,IE使用nodes[i].childNodes[j].text,Chrome使用nodes[i].childNodes[j].textContent,其他瀏覽器我沒一一確認過
2.canvas物件初始化(忍不住小小抱怨一下這個xx邦的介面好難用.....)
	var c = document.getElementById(canvasF);
    try { c.getContext("2d") }
    catch (e) { canvasIni(); }	
這個canvasIni(),是我將excanvas.js裡的函式再包裝成canvasIni()方法,以方便當我存取getContext方法失敗時可以再呼叫canvas初始化一次,至於excanvas.js檔看倌可自行google->excanvas.js,會有很多版本,你可以一一自己試試看各別版本效果有何不同
3.canvas滑鼠事件處理
  try {
        //非IE
        c.addEventListener("mousemove", function (a) {
        //滑鼠x位置  a.clientX; 滑鼠在canvas的相對位置a.offsetX;  canvas位置 left c.offsetLeft;
            if (c == null || c == undefined || (!c)) {
                c = document.getElementById(canvasF);
            }                
            var ctx = c.getContext("2d");
            //你的畫圖程式放在這
}
catch(e)
{
         //IE
        c.attachEvent("onmousemove", function (a) {
            //滑鼠x位置  a.clientX; 滑鼠在canvas的相對位置a.offsetX;  canvas位置 left c.offsetLeft;
                if (c == null || c == undefined || (!c)) {
                    c = document.getElementById(canvasF);
                }  
              var ctx = c.getContext("2d");
            //你的畫圖程式放在這     
}
由上可看出,滑鼠事件在ie與非ie中,事件名稱不同,其他繪圖方法都一樣,但是這裡有一點要注意,我測試的結果中,IE往往top與left會比其他瀏覽器多了一點點px出來,導致算出來的位置有點偏移
4.治療王子公主病~~IE8
我發現如果網頁內容單純,canvas放在網頁最上面,執行結果都很OK~但是偏偏我家老闆很愛一條龍式的網頁排版,滑鼠中軌捲軸硬是要往下捲了3次以上,才能滑到網頁最後的內容,如果網頁內容很多時,奇怪,原來好好的canvas畫圖就錯了,還一直跟我說錯在var ctx = c.getContext("2d"),在IE8時我明明就有加<!--[if IE]><script type="text/javascript" src="js/excanvasTxt.js"></script><![endif]-->啊
這邊害我卡住非常久,原本以為是excanvas.js裡的方法沒寫好,後來發現,是excanvas在把canvas物件加上event時找不到該物件,WHY?因為ie載入html Object速度較慢,而excanvas.js在執行時html object還沒產生,所以cancas初始化這件事根本沒做~
於是乎~~我只好寫了委派事件(是叫委派嗎?小的才疏學淺不敢確定,但覺得這種寫法很像是委派)
總之就是讓網頁去判斷當html 載入完成後,才去做canvas初始化這件事
//事件listion處理
function waitObject(testobj, fun) {
    if (document.readyState != 'complete') {
        var c = document.getElementById(testobj);
        if (c.attachEvent)//僅針對ie未load完document物件做處理  
        { addLoadListener(fun); }
        else
        { throw "Broswer is not IE,don't use this function."; }
    }
    else
    { fun(); }
}
function addLoadListener(fn) {
    if (typeof window.addEventListener != 'undefined') {
        window.addEventListener('load', fn, false);
    }
    else if (typeof document.addEventListener != 'undefined') {
        document.addEventListener('load', fn, false);
    }
    else if (typeof window.attachEvent != 'undefined') {   //ie
        try {
            window.attachEvent('onload', fn);
        }
        catch (e)
			{ throw e; }
    }
    else {
        var oldfn = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = fn;
        }
        else {
            window.onload = function () {
                oldfn();
                fn();
            };
        }
    }
}
//我將繪圖方法包裝成drawCharBasic(canvasF)這個函式裡,方便後面呼叫引用
    	var c = document.getElementById(canvasF);
    	var cfun = function cfunf() { drawCharBasic(canvasF); };
	    if (c.attachEvent)//IE 特別處理 
	    { waitObject(canvasF, cfun); }
	    else
	    { drawCharBasic(canvasF); }
沒有demo網頁,真的有人能體會我在寫什麼嗎?.....冏
說實話我沒有推薦什麼library,但是我要說,基本功練好了,library就能輕易上手,大家取方法屬性的名稱都大同小異,基本的會了,library在使用上就難不倒你
我沒有依主題發表適當內容,但是這裡沒有暫存的草稿功能,所以...沒關係,發了就算了
如果你有忍耐著看到這裡,想必看官canvas的功力也增進了不少,但是我要告訴你,還有個東西叫svg,正準備取代canvas....
終於有大大PO文了~~!
小弟的拋磚文 也功成身退 壽終正寢![]()
功成身退,百姓皆曰我自然 ![]()
ted99tw提到:
自然
我...我數學....![]()
呵呵~~Javascript我也都自己寫一套~
JQ是懶人在用的~除非客戶自己想要那樣的風格~
不然Javascript我都寧願,萬丈高樓平地起~
jer5173提到:
JQ是懶人在用的
難怪大大會怕被列入黑名單...![]()
呵呵~~![]()
jer5173提到:
JQ是懶人
...
jer5173提到:
JQ是懶人
...
還是用YUI好了....![]()
不過這樣最後也是要發展出自己一套框架吧,不然不同瀏覽器的行為處理,也是會累死人的
![]()
有些東西不是不交出來,是要人時地利人合,沒有遇到能理解的人,PO出來恐怕沒有人能看懂
如果有空,改天我再寫個svg實做測試版本的好了~~if...
milienchen提到:
人合
![]()